﻿# 

use strict;
use warnings;
use seo_crawler;
use Data::Dumper;
use FindBin;
use lib $FindBin::Bin;
use Getopt::Long;
use MIME::Base64;
use WWW::Google::PageRank;
use domain_list;
use URI;

my $VERSION="v1.0.5 beta";

# Процедуру получения страниц сайта можно сделать рекурсивной, но это менее контролируемо. И здесь приходится реализовывать
# или событийную модель, то есть мы указываем функции, которые будут вызываться в случае получения роботом страницы, которая
# отвечает нашим критериям, или же делать рекурсию. Но также обход страниц можно реализовать бесконечным циклом, выход
# из которого происходит при наступлении определенного события, например, когда нет ссылок для обработки.

# также вводится некоторое понятие внутренней структуры, которая хранит всю информацию о странице, которую загрузил робот
# Это позволяет, перед получением новой страницы сохранять эту структуру в виде файла, для того, чтобы позже
# можно было продолжить работу, если, например, вдруг будут какие-либо проблемы со связью.
#
#

#my $sc=new seo_crawler("http://www.site/Neitrino/index.php", 	# url
#								2,								# max_level
#								"www.site"					# base_domain
#								);

#my $sc=new seo_crawler("http://www.site/Neitrino/index.php", 	# url
#								3,								# max_level
#								"www.site"					# base_domain
#								);

# если мы указываем url - http://www.site/ и bas_domain
#
#
#

sub usage()
{
    die <<EOF;
Invalid arguments.

Example: seo_crawler.exe --site=http://lib.ru --domain=lib.ru --level=1
	you can skip --domain and --level parameters.
EOF
}

my $start_url;
my $base_domain;
my $level;

my $domain_count={};

my $dt = new domain_list();


print "\nseo_crawler.exe $VERSION. http://wr-blog.ru/seo-robot/ - 2012. All rights reserved.\n\n";

GetOptions ("site=s"   => \$start_url,
				"domain=s"   => \$base_domain,
             "level=i"   => \$level
			 ) or usage();

# Далее есть сравнение if ($can_url=~/(http|https)\:\/\/[^\/]*$base_domain/) поэтому необходимо учесть, что вводит пользователь. Если - site=http://domain.com/

if (!defined($start_url) || $start_url!~/^\S+$/)
{
	usage();
}

if ($start_url!~/http/)
{
	$start_url = "http://" . $start_url;
}

$start_url=~s/(.+?)\s+$/$1/;
$start_url=~s/(.+?)\/$/$1/;

if (!defined($base_domain) || $base_domain!~/^\S+$/)
{

	my $tmp_uri = new URI($start_url);
	
	# получаем базовые домен для проверки внешних, внутренних ссылок
	# для trudogolik.com.ua - это будет trugogolik.com.ua
	# а для txt.lib.ru - lib.ru
	$base_domain = $dt->check($tmp_uri->host);
	
	print "[Info:] Default base domain is: " . $base_domain . "\n";
	
}

if (!defined($level) || $level!~/^\d+$/)
{
	$level = 1;
	print "[Info:] Default level is 1\n";
	#usage();
}

my $curr_dir = $FindBin::Bin;

my $rep_dir=$curr_dir."/".$base_domain;
mkdir $rep_dir;


my $conf_rep={};

open (my $outer_links_rep,">",$rep_dir."/outer_links.txt");

my $oldfh=select($outer_links_rep);
$|=1;
select($oldfh);


$conf_rep->{outer_links_rep}=$outer_links_rep;
$conf_rep->{domain_count}=$domain_count;

my $sc=new seo_crawler($start_url, 	# url
								$level,								# max_level
								$base_domain,					# base_domain шаблон для определения внутренних ссылок
								\&url_hndl,
								$rep_dir,
                        $conf_rep
								);



$sc->go();

# print Dumper ($sc);

sub url_hndl
{
	# функция обратного вызова
	# вызывается после того как пройден какой-либо URL
	# на входе указатель на структуру описывающей данные по определенному URL

	my $strct=shift;
	my $rep_dir=shift;
	my $conf_rep=shift;
	my $self=shift;

	my @tmp_arr_for_sort;



	foreach my $el(@{$strct->{outer_links}->{all_links}})
	{
		my $tmp_key=encode_base64(seo_crawler::get_domain_from_url($el->{orig_url}));
		$conf_rep->{domain_count}->{$tmp_key}->{links_count}++;
	}

	foreach my $key (keys %{$conf_rep->{domain_count}})
	{
		push @tmp_arr_for_sort,{url=>$key,links_count=>$conf_rep->{domain_count}->{$key}->{links_count}};
	}

#	print "\nSorting result....\n";



	@tmp_arr_for_sort=sort {$b->{links_count} <=> $a->{links_count}} @tmp_arr_for_sort;

	open (my $stat,">",$rep_dir."/stat.txt");

	print $stat "Всего внешних ссылок: ".$self->{outer_links_count}."\n";
	print $stat "    без nofollow и без noindex: ".		$self->{outer_links_count_not_nf_and_ni}."\n";
	print $stat "    только с nofollow: ".$self->{outer_links_count_not_ni}."\n";
	print $stat "    только в noindex: ".$self->{outer_links_count_not_nf}."\n";
	print $stat "    с nofollow и в noindex: ".$self->{outer_links_count_nf_and_ni}."\n";

	print $stat "Страниц сайта: ".$self->{pages_count}."\n";

	my $tmp_r=$self->{outer_links_count}/$self->{pages_count};

	print $stat "Соотношение к-ва внешних ссылок к к-ству страниц сайта: ".$tmp_r."\n";
		
	close $stat;


	open (my $domain_count,">",$rep_dir."/domain_counts.txt");

	foreach my $el(@tmp_arr_for_sort)
	{
		print $domain_count decode_base64($el->{url})." ".$el->{links_count}."\n";
	}

	close $domain_count;
#	print Dumper(@tmp_arr_for_sort);
	my $pr = WWW::Google::PageRank->new;

	print {$conf_rep->{outer_links_rep}} "\n[ PR=";
		
	my $tmp_pr=scalar($pr->get($strct->{url}));
	if (!defined($tmp_pr)) {$tmp_pr=0;}
		
	print {$conf_rep->{outer_links_rep}} $tmp_pr;
	print {$conf_rep->{outer_links_rep}} " ] ";

	print {$conf_rep->{outer_links_rep}} "URL:   ".$strct->{url}."\n";

#	print Dumper($strct);

#	print "callback\n";
	foreach my $el(@{$strct->{outer_links}->{all_links}})
	{
		my $noindex="";
		my $nofollow="";

		if ($el->{noindex})
		{
			$noindex="noindex";
		}		

		if ($el->{nofollow})
		{
			$nofollow="nofollow";
		}

		print {$conf_rep->{outer_links_rep}} "[".$noindex." ".$nofollow."]".$el->{orig_url}."\n";
	}

	



#	foreach my $tmp_el (	@tmp_arr_for_sort )
#	{
#		print $domain_count decode_base64
#	}


#	my @keys=keys (%{$conf_rep->{domain_count}});

#	foreach my $key_b64(@keys)
#	{
#		print $domain_count decode_base64($key_b64)." ".$conf_rep->{domain_count}->{$key_b64}."\n";
#	}
#	print Dumper($strct);

#	close ($domain_count);

}

#print Dumper($sc->{kernel});